///************************************************************************
/// <copyrigth>2018-2019 Corporation.All Rights Reserved</copyrigth>
/// <author>tangyingzhong</author>
/// <contact>tangyz114987@outlook.com</contact>
/// <version>v1.0.0</version>
/// <describe>
/// Render the data by d3d of windows
///</describe>
/// <date>2021/6/26</date>
///***********************************************************************
#ifndef IVIDEOD3DRENDER_H
#define IVIDEOD3DRENDER_H

#include <string>
extern "C" {
#include <libavutil/frame.h>
#include <libavutil/avutil.h>
#include <libavutil/opt.h>
#include <libavutil/common.h>
#include <libavutil/hwcontext.h>
#include <libavutil/imgutils.h>
#include <libavutil/avassert.h>
#include <libavutil/buffer.h>
#include <libavutil/frame.h>
#include <libavutil/pixfmt.h>
#include <libavcodec/avcodec.h>
#include <libavcodec/dxva2.h>
}

// Hard accelerate id
enum HWAccelID
{
	HWACCEL_NONE = 0,
	HWACCEL_AUTO,
	HWACCEL_VDPAU,
	HWACCEL_DXVA2,
	HWACCEL_VDA,
	HWACCEL_VIDEOTOOLBOX,
	HWACCEL_QSV,
};

// Input stream
struct InputStream
{
	// Hard accelerate id
	HWAccelID eHwAccelId;

	// Active hard accelerate id
	HWAccelID eActiveHwAccelId;

	// Hard accelerate device
	std::string strHwAccelDeviceName;

	// Pixel format
	AVPixelFormat HwPixelFormat;

	// Video Codec
	AVCodec* pAvCodec;

	// Codec context
	AVCodecContext* pAvCodecContext;

	// Hard decode context
	void* pHwaccelContext;

	// Uint hard accelerate
	void(*hwaccel_uninit)(AVCodecContext* s);

	// Get buffer of hard accelerate
	int(*hwaccel_get_buffer)(AVCodecContext* s, AVFrame* frame, int flags);

	// Get hard accelerate data
	int(*hwaccel_retrieve_data)(AVCodecContext* s, AVFrame* frame);
};

class IVideoD3dRender
{
public:
	// Detructe the IVideoD3dRender
	virtual ~IVideoD3dRender() {	}

public:
	// Initialize the render
	virtual bool Init(AVCodecContext* pAvctx, void* pWindowHandle) = 0;

	// Render the data
	virtual bool Render(AVFrame* pFrame) = 0;
};

#endif // IVIDEOD3DRENDER_H
